/**
 *  Copyright (c) 2012-2016, www.tinygroup.org (luo_guo@icloud.com).
 *
 *  Licensed under the GPL, Version 3.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *       http://www.gnu.org/licenses/gpl.html
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

package org.tinygroup.sdpm.project.dao.impl;

import org.springframework.stereotype.Repository;
import static org.tinygroup.tinysqldsl.base.StatementSqlBuilder.and;
import static org.tinygroup.sdpm.project.dao.constant.ProjectTeamTable.*;
import static org.tinygroup.tinysqldsl.Select.*;
import static org.tinygroup.tinysqldsl.Insert.*;
import static org.tinygroup.tinysqldsl.Delete.*;
import static org.tinygroup.tinysqldsl.Update.*;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import static org.tinygroup.sdpm.org.dao.constant.OrgRoleMenuTable.ORG_ROLE_MENUTABLE;
import static org.tinygroup.sdpm.org.dao.constant.OrgRoleTable.ORG_ROLETABLE;
import static org.tinygroup.sdpm.project.dao.constant.ProjectTeamTable.PROJECT_TEAMTABLE;
import static org.tinygroup.tinysqldsl.Delete.delete;
import static org.tinygroup.tinysqldsl.Insert.insertInto;
import static org.tinygroup.tinysqldsl.Select.selectFrom;
import static org.tinygroup.tinysqldsl.Update.update;
import java.sql.Date;

import org.tinygroup.tinysqldsl.Delete;
import org.tinygroup.tinysqldsl.Insert;
import org.tinygroup.tinysqldsl.Select;
import org.tinygroup.tinysqldsl.Update;
import org.tinygroup.tinysqldsl.Pager;

import org.tinygroup.commons.tools.CollectionUtil;
import org.tinygroup.commons.tools.StringUtil;
import org.tinygroup.jdbctemplatedslsession.callback.*;
import org.tinygroup.tinysqldsl.expression.JdbcNamedParameter;
import org.tinygroup.tinysqldsl.extend.MysqlSelect;
import org.tinygroup.tinysqldsl.select.Join;
import org.tinygroup.tinysqldsl.select.OrderByElement;

import org.tinygroup.sdpm.project.dao.pojo.ProjectTeam;
import org.tinygroup.tinysqldsl.*;
import org.tinygroup.sdpm.project.dao.ProjectTeamDao;

import org.tinygroup.jdbctemplatedslsession.daosupport.OrderBy;
import org.tinygroup.jdbctemplatedslsession.daosupport.TinyDslDaoSupport;
import org.tinygroup.jdbctemplatedslsession.callback.InsertGenerateCallback;
import org.tinygroup.jdbctemplatedslsession.callback.DeleteGenerateCallback;
import org.tinygroup.jdbctemplatedslsession.callback.SelectGenerateCallback;
import org.tinygroup.jdbctemplatedslsession.callback.UpdateGenerateCallback;
import org.tinygroup.jdbctemplatedslsession.callback.NoParamDeleteGenerateCallback;
import org.tinygroup.jdbctemplatedslsession.callback.NoParamInsertGenerateCallback;
import org.tinygroup.jdbctemplatedslsession.callback.NoParamUpdateGenerateCallback;
import org.tinygroup.jdbctemplatedslsession.util.TinyDSLUtil;

/**
 * <!-- begin-user-doc --> 如果不希望某方法或者变量被覆盖，可以在方法或者变量注释中增加@unmodifiable <!--
 * end-user-doc -->
 */
@Repository
public class ProjectTeamDaoImpl extends TinyDslDaoSupport implements
		ProjectTeamDao {

	public List<ProjectTeam> findByProjectId(Integer projectId) {
		Select select = selectFrom(PROJECT_TEAMTABLE).where(
				PROJECT_TEAMTABLE.PROJECT_ID.eq(projectId));
		return getDslSession().fetchList(select, ProjectTeam.class);
	}

	public List<ProjectTeam> findByProductId(Integer productId) {
		Select select = selectFrom(PROJECT_TEAMTABLE).where(
				PROJECT_TEAMTABLE.PRODUCT_ID.eq(productId));
		return getDslSession().fetchList(select, ProjectTeam.class);
	}

	public List<String> getMenuByUserId(Integer projectId, Integer productId,
			String userId) {
		List<Integer> roleIdListByProjectIdAndUserId = getRoleIdListByUserId(
				projectId, productId, userId);
		if (CollectionUtil.isEmpty(roleIdListByProjectIdAndUserId)) {
			return new ArrayList<String>();
		}
		Select select = Select
				.select(ORG_ROLE_MENUTABLE.ORG_ROLE_MENU_ID)
				.from(ORG_ROLE_MENUTABLE)
				.where(ORG_ROLE_MENUTABLE.ORG_ROLE_ID
						.in(roleIdListByProjectIdAndUserId.toArray()));
		return getDslSession().fetchList(select, String.class);
	}

	public List<Integer> getRoleIdListByUserId(Integer projectId,
			Integer productId, String userId) {
		List<Integer> roleIdList = new ArrayList<Integer>();
		ProjectTeam projectTeam = new ProjectTeam();
		projectTeam.setProjectId(projectId);
		projectTeam.setTeamUserId(userId);
		projectTeam.setProductId(productId);
		List<ProjectTeam> list = query(projectTeam);
		if (!CollectionUtil.isEmpty(list)) {
			projectTeam = list.get(0);
			String teamRole = projectTeam.getTeamRole();
			if (!StringUtil.isBlank(teamRole)) {
				String[] split = teamRole.split(",");
				for (String roleId : split) {
					if (StringUtil.isBlank(roleId)) {
						continue;
					}
					roleIdList.add(Integer.valueOf(roleId));
				}
			}
		}
		return roleIdList;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 */
	public ProjectTeam add(ProjectTeam projectTeam) {
		return getDslTemplate().insertAndReturnKey(projectTeam,
				new InsertGenerateCallback<ProjectTeam>() {
					public Insert generate(ProjectTeam t) {
						Insert insert = insertInto(PROJECT_TEAM_TABLE).values(
								PROJECT_TEAM_TABLE.ID.value(t.getId()),
								PROJECT_TEAM_TABLE.PRODUCT_ID.value(t
										.getProductId()),
								PROJECT_TEAM_TABLE.PROJECT_ID.value(t
										.getProjectId()),
								PROJECT_TEAM_TABLE.TEAM_USER_ID.value(t
										.getTeamUserId()),
								PROJECT_TEAM_TABLE.TEAM_ROLE.value(t
										.getTeamRole()),
								PROJECT_TEAM_TABLE.TEAM_JOIN.value(t
										.getTeamJoin()),
								PROJECT_TEAM_TABLE.TEAM_DAYS.value(t
										.getTeamDays()),
								PROJECT_TEAM_TABLE.TEAM_HOURS.value(t
										.getTeamHours())

						);
						return insert;
					}
				});
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 */
	public int edit(ProjectTeam projectTeam) {
		if (projectTeam == null || projectTeam.getId() == null) {
			return 0;
		}
		return getDslTemplate().update(projectTeam,
				new UpdateGenerateCallback<ProjectTeam>() {
					public Update generate(ProjectTeam t) {
						Update update = update(PROJECT_TEAM_TABLE).set(
								PROJECT_TEAM_TABLE.PRODUCT_ID.value(t
										.getProductId()),
								PROJECT_TEAM_TABLE.PROJECT_ID.value(t
										.getProjectId()),
								PROJECT_TEAM_TABLE.TEAM_USER_ID.value(t
										.getTeamUserId()),
								PROJECT_TEAM_TABLE.TEAM_ROLE.value(t
										.getTeamRole()),
								PROJECT_TEAM_TABLE.TEAM_JOIN.value(t
										.getTeamJoin()),
								PROJECT_TEAM_TABLE.TEAM_DAYS.value(t
										.getTeamDays()),
								PROJECT_TEAM_TABLE.TEAM_HOURS.value(t
										.getTeamHours())).where(
								PROJECT_TEAM_TABLE.ID.eq(t.getId()));
						return update;
					}
				});
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 */
	public int deleteByKey(Integer pk) {
		if (pk == null) {
			return 0;
		}
		return getDslTemplate().deleteByKey(pk,
				new DeleteGenerateCallback<Serializable>() {
					public Delete generate(Serializable pk) {
						return delete(PROJECT_TEAM_TABLE).where(
								PROJECT_TEAM_TABLE.ID.eq(pk));
					}
				});
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 */
	public int deleteByKeys(Integer... pks) {
		if (pks == null || pks.length == 0) {
			return 0;
		}
		return getDslTemplate().deleteByKeys(
				new DeleteGenerateCallback<Serializable[]>() {
					public Delete generate(Serializable[] t) {
						return delete(PROJECT_TEAM_TABLE).where(
								PROJECT_TEAM_TABLE.ID.in(t));
					}
				}, pks);
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 */
	public ProjectTeam getByKey(Integer pk) {
		return getDslTemplate().getByKey(pk, ProjectTeam.class,
				new SelectGenerateCallback<Serializable>() {

					@SuppressWarnings("rawtypes")
					public Select generate(Serializable t) {
						return selectFrom(PROJECT_TEAM_TABLE).where(
								PROJECT_TEAM_TABLE.ID.eq(t));
					}
				});
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 */
	public List<ProjectTeam> query(ProjectTeam projectTeam,
			final OrderBy... orderArgs) {
		if (projectTeam == null) {
			projectTeam = new ProjectTeam();
		}
		return getDslTemplate().query(projectTeam,
				new SelectGenerateCallback<ProjectTeam>() {
					@SuppressWarnings("rawtypes")
					public Select generate(ProjectTeam t) {
						Select select = selectFrom(PROJECT_TEAM_TABLE).where(
								and(PROJECT_TEAM_TABLE.ID.eq(t.getId()),
										PROJECT_TEAM_TABLE.PRODUCT_ID.eq(t
												.getProductId()),
										PROJECT_TEAM_TABLE.PROJECT_ID.eq(t
												.getProjectId()),
										PROJECT_TEAM_TABLE.TEAM_USER_ID.eq(t
												.getTeamUserId()),
										PROJECT_TEAM_TABLE.TEAM_ROLE.eq(t
												.getTeamRole()),
										PROJECT_TEAM_TABLE.TEAM_JOIN.eq(t
												.getTeamJoin()),
										PROJECT_TEAM_TABLE.TEAM_DAYS.eq(t
												.getTeamDays()),
										PROJECT_TEAM_TABLE.TEAM_HOURS.eq(t
												.getTeamHours())

								));
						return TinyDSLUtil
								.addOrderByElements(select, orderArgs);
					}
				});
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 */
	public Pager<ProjectTeam> queryPager(int start, int limit,
			ProjectTeam projectTeam, final OrderBy... orderArgs) {
		if (projectTeam == null) {
			projectTeam = new ProjectTeam();
		}
		return getDslTemplate().queryPager(start, limit, projectTeam, false,
				new SelectGenerateCallback<ProjectTeam>() {
					public Select generate(ProjectTeam t) {
						Select select = Select.selectFrom(PROJECT_TEAM_TABLE)
								.where(and(PROJECT_TEAM_TABLE.ID.eq(t.getId()),
										PROJECT_TEAM_TABLE.PRODUCT_ID.eq(t
												.getProductId()),
										PROJECT_TEAM_TABLE.PROJECT_ID.eq(t
												.getProjectId()),
										PROJECT_TEAM_TABLE.TEAM_USER_ID.eq(t
												.getTeamUserId()),
										PROJECT_TEAM_TABLE.TEAM_ROLE.eq(t
												.getTeamRole()),
										PROJECT_TEAM_TABLE.TEAM_JOIN.eq(t
												.getTeamJoin()),
										PROJECT_TEAM_TABLE.TEAM_DAYS.eq(t
												.getTeamDays()),
										PROJECT_TEAM_TABLE.TEAM_HOURS.eq(t
												.getTeamHours())

								));
						return TinyDSLUtil
								.addOrderByElements(select, orderArgs);
					}
				});
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 */
	public int[] batchInsert(boolean autoGeneratedKeys,
			List<ProjectTeam> projectTeam) {
		if (CollectionUtil.isEmpty(projectTeam)) {
			return new int[0];
		}
		return getDslTemplate().batchInsert(autoGeneratedKeys, projectTeam,
				new InsertGenerateCallback<ProjectTeam>() {

					public Insert generate(ProjectTeam t) {
						return insertInto(PROJECT_TEAM_TABLE).values(
								PROJECT_TEAM_TABLE.ID.value(t.getId()),
								PROJECT_TEAM_TABLE.PRODUCT_ID.value(t
										.getProductId()),
								PROJECT_TEAM_TABLE.PROJECT_ID.value(t
										.getProjectId()),
								PROJECT_TEAM_TABLE.TEAM_USER_ID.value(t
										.getTeamUserId()),
								PROJECT_TEAM_TABLE.TEAM_ROLE.value(t
										.getTeamRole()),
								PROJECT_TEAM_TABLE.TEAM_JOIN.value(t
										.getTeamJoin()),
								PROJECT_TEAM_TABLE.TEAM_DAYS.value(t
										.getTeamDays()),
								PROJECT_TEAM_TABLE.TEAM_HOURS.value(t
										.getTeamHours())

						);
					}
				});
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 */
	public int[] batchInsert(List<ProjectTeam> projectTeams) {
		return batchInsert(true, projectTeams);
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 */
	public int[] batchUpdate(List<ProjectTeam> projectTeam) {
		if (CollectionUtil.isEmpty(projectTeam)) {
			return new int[0];
		}
		return getDslTemplate().batchUpdate(projectTeam,
				new UpdateGenerateCallback<ProjectTeam>() {
					public Update generate(ProjectTeam t) {
						return update(PROJECT_TEAM_TABLE).set(
								PROJECT_TEAM_TABLE.PRODUCT_ID.value(t
										.getProductId()),
								PROJECT_TEAM_TABLE.PROJECT_ID.value(t
										.getProjectId()),
								PROJECT_TEAM_TABLE.TEAM_USER_ID.value(t
										.getTeamUserId()),
								PROJECT_TEAM_TABLE.TEAM_ROLE.value(t
										.getTeamRole()),
								PROJECT_TEAM_TABLE.TEAM_JOIN.value(t
										.getTeamJoin()),
								PROJECT_TEAM_TABLE.TEAM_DAYS.value(t
										.getTeamDays()),
								PROJECT_TEAM_TABLE.TEAM_HOURS.value(t
										.getTeamHours())

						).where(PROJECT_TEAM_TABLE.ID.eq(t.getId()));
					}
				});
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 */
	public int[] batchDelete(List<ProjectTeam> projectTeam) {
		if (CollectionUtil.isEmpty(projectTeam)) {
			return new int[0];
		}

		return getDslTemplate().batchDelete(projectTeam,
				new DeleteGenerateCallback<ProjectTeam>() {
					public Delete generate(ProjectTeam t) {
						return delete(PROJECT_TEAM_TABLE).where(
								and(PROJECT_TEAM_TABLE.ID.eq(t.getId()),
										PROJECT_TEAM_TABLE.PRODUCT_ID.eq(t
												.getProductId()),
										PROJECT_TEAM_TABLE.PROJECT_ID.eq(t
												.getProjectId()),
										PROJECT_TEAM_TABLE.TEAM_USER_ID.eq(t
												.getTeamUserId()),
										PROJECT_TEAM_TABLE.TEAM_ROLE.eq(t
												.getTeamRole()),
										PROJECT_TEAM_TABLE.TEAM_JOIN.eq(t
												.getTeamJoin()),
										PROJECT_TEAM_TABLE.TEAM_DAYS.eq(t
												.getTeamDays()),
										PROJECT_TEAM_TABLE.TEAM_HOURS.eq(t
												.getTeamHours())

								));
					}
				});
	}

	private Select addOrderByElements(Select select, OrderBy... orderByArgs) {
		List<OrderByElement> orderByElements = new ArrayList<OrderByElement>();
		for (int i = 0; orderByArgs != null && i < orderByArgs.length; i++) {
			OrderByElement tempElement = orderByArgs[i].getOrderByElement();
			if (tempElement != null) {
				orderByElements.add(tempElement);
			}
		}
		if (orderByElements.size() > 0) {
			select.orderBy(orderByElements.toArray(new OrderByElement[0]));
		}
		return select;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 */
	public int[] preparedBatchInsert(boolean autoGeneratedKeys,
			List<ProjectTeam> projectTeam) {
		if (CollectionUtil.isEmpty(projectTeam)) {
			return new int[0];
		}
		return getDslTemplate().batchInsert(autoGeneratedKeys, projectTeam,
				new NoParamInsertGenerateCallback() {

					public Insert generate() {
						return insertInto(PROJECT_TEAM_TABLE).values(
								PROJECT_TEAM_TABLE.PRODUCT_ID
										.value(new JdbcNamedParameter(
												"productId")),
								PROJECT_TEAM_TABLE.PROJECT_ID
										.value(new JdbcNamedParameter(
												"projectId")),
								PROJECT_TEAM_TABLE.TEAM_USER_ID
										.value(new JdbcNamedParameter(
												"teamUserId")),
								PROJECT_TEAM_TABLE.TEAM_ROLE
										.value(new JdbcNamedParameter(
												"teamRole")),
								PROJECT_TEAM_TABLE.TEAM_JOIN
										.value(new JdbcNamedParameter(
												"teamJoin")),
								PROJECT_TEAM_TABLE.TEAM_DAYS
										.value(new JdbcNamedParameter(
												"teamDays")),
								PROJECT_TEAM_TABLE.TEAM_HOURS
										.value(new JdbcNamedParameter(
												"teamHours"))

						);
					}
				});
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 */
	public int[] preparedBatchUpdate(List<ProjectTeam> projectTeam) {
		if (CollectionUtil.isEmpty(projectTeam)) {
			return new int[0];
		}
		return getDslTemplate().batchUpdate(projectTeam,
				new NoParamUpdateGenerateCallback() {
					public Update generate() {
						return update(PROJECT_TEAM_TABLE).set(
								PROJECT_TEAM_TABLE.PRODUCT_ID
										.value(new JdbcNamedParameter(
												"productId")),
								PROJECT_TEAM_TABLE.PROJECT_ID
										.value(new JdbcNamedParameter(
												"projectId")),
								PROJECT_TEAM_TABLE.TEAM_USER_ID
										.value(new JdbcNamedParameter(
												"teamUserId")),
								PROJECT_TEAM_TABLE.TEAM_ROLE
										.value(new JdbcNamedParameter(
												"teamRole")),
								PROJECT_TEAM_TABLE.TEAM_JOIN
										.value(new JdbcNamedParameter(
												"teamJoin")),
								PROJECT_TEAM_TABLE.TEAM_DAYS
										.value(new JdbcNamedParameter(
												"teamDays")),
								PROJECT_TEAM_TABLE.TEAM_HOURS
										.value(new JdbcNamedParameter(
												"teamHours"))

						).where(PROJECT_TEAM_TABLE.ID
								.eq(new JdbcNamedParameter("id")));
					}
				});
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 */
	public int[] preparedBatchDelete(List<ProjectTeam> projectTeam) {
		if (CollectionUtil.isEmpty(projectTeam)) {
			return new int[0];
		}

		return getDslTemplate().batchDelete(projectTeam,
				new NoParamDeleteGenerateCallback() {
					public Delete generate() {
						return delete(PROJECT_TEAM_TABLE)
								.where(and(
										PROJECT_TEAM_TABLE.PRODUCT_ID
												.eq(new JdbcNamedParameter(
														"productId")),
										PROJECT_TEAM_TABLE.PROJECT_ID
												.eq(new JdbcNamedParameter(
														"projectId")),
										PROJECT_TEAM_TABLE.TEAM_USER_ID
												.eq(new JdbcNamedParameter(
														"teamUserId")),
										PROJECT_TEAM_TABLE.TEAM_ROLE
												.eq(new JdbcNamedParameter(
														"teamRole")),
										PROJECT_TEAM_TABLE.TEAM_JOIN
												.eq(new JdbcNamedParameter(
														"teamJoin")),
										PROJECT_TEAM_TABLE.TEAM_DAYS
												.eq(new JdbcNamedParameter(
														"teamDays")),
										PROJECT_TEAM_TABLE.TEAM_HOURS
												.eq(new JdbcNamedParameter(
														"teamHours"))

								));
					}
				});
	}

	public int[] preparedBatchInsert(List<ProjectTeam> projectTeam) {
		return preparedBatchInsert(true, projectTeam);
	}

}
